import { Button, Form, Input, FormProps, Row, Col, Table } from "antd"
import Descriptions from '../Descriptions'
import './index.less'
import { DeleteOutlined } from "@ant-design/icons"
import React, { useContext, useMemo } from "react"
import { Rule } from "antd/lib/form"
interface ItemsProps {
    label?: string
    name?: string
    shouldUpdate?: boolean | (() => boolean)
    show?: boolean | ((formData) => boolean)
    children?: React.ReactNode
    render?: (value: any, record: any, index: number) => React.ReactNode
    span?: number
    rules?: Rule[]
    disabled?: boolean
    [key: string]: any
}
interface PanelProps {
    items: ItemsProps[]
    title?: string
    index?: number
    column?: any
    // layout?: 'horizontal' | 'vertical';
    extra?: React.ReactNode
    labelWidth?: string | number
    [key: string]: any

}
const Panel = ({ items, title, index, column = 1, labelCol, extra, ...rest }: PanelProps) => {

    let { layout, labelWidth, labelAlign } = useContext(FormControlContext)
    labelWidth = rest.labelWidth || labelWidth || 65
    const formItems = useMemo(() => {
        return items.map(({ disabled, ...item }) => {

            let { children = <Input disabled={disabled} placeholder={`请输入${item.label}`} />, show, shouldUpdate, ...rest } = item
            const name = index !== undefined ? [index, item.name] : item.name;
            if (item.label && Array.isArray(item.rules)) {
                const requiredRule: any = item.rules.find((v: any) => v.required && !v.message);
                if (requiredRule) {
                    requiredRule.message = `请输入${item.label}`
                }
            }
            if (item.hidden) {
                
               return null
            }
            const defaultFormItemInput = <Form.Item
                {...item}
                name={name}
                label={<div className="ant-form-item-label-width" style={{ width: layout === 'vertical' ? '100%' : labelWidth }}    >{item.label}</div>}
                style={{ width: '100%' }}>
                {children}
            </Form.Item>
            let formItemInput = null;

            if (shouldUpdate) {
                formItemInput = <Form.Item noStyle shouldUpdate={shouldUpdate}>
                    {({ getFieldsValue }) => {
                        const formData = getFieldsValue()
                        if (typeof show === 'function') {

                            return show(formData) ? defaultFormItemInput : null
                        }
                        return show ? defaultFormItemInput : null
                    }}
                </Form.Item>
            }

            return {
                ...item,
                label: null,
                children:item.hidden?null: defaultFormItemInput
            }
        })
    }, [items])
    // return <Row>
    //     {formItems}
    // </Row>
    return <Descriptions layout={layout} column={column} extra={extra} title={title} items={formItems} />

}


interface ListProps {
    title?: string
    addText?: string
    name: string
    column?: any
    items: ItemsProps[]
    maxCount?: number
    minCount?: number
    tabel?: boolean
    renderItem?: (e: any) => React.ReactNode
}
const List = ({ items, renderItem, tabel, maxCount = 1000, minCount = 1, column, addText, name, title }: ListProps) => {
    const {disabled} = useContext(FormControlContext)
    // const listItems = items.map(item=>{
    //     return {
    //         ...item,
    //         name:[item.name]
    //     }
    // })
    return <Form.List name={name}>{(fields, { add, remove }) => {
        if (tabel) {
            const columns = [
                ...items.map(v => {
                   const {disabled} = v
                    let { children = <Input disabled={disabled}   placeholder={`请输入${v.label}`} />, render, show, shouldUpdate, ...rest } = v

                    return {
                        title: v.label,
                        render: render ? render : (value, record: any, index) => {
                            return <Form.Item name={[index, v.name]}>
                                {children}
                            </Form.Item>
                        }
                    }
                }),
                {
                    title: '操作',
                    render(e, ee, index) {
                        return <Form.Item >
                            <Button hidden={disabled} onClick={() => remove(fields[index].name)} danger size='small'>删除</Button>
                        </Form.Item>
                    }
                }
            ]
            return <div>
                <Table pagination={false} size='small' dataSource={fields} columns={columns} />
                <Button hidden={disabled} disabled={maxCount <= fields.length} type='dashed' block onClick={() => add({})}>{addText ? addText : '增加' + title}</Button>
            </div>
        }
        return <FormControl.Group>
            {fields.map((item, index) => {
                if (renderItem) {
                    return <div key={item.key}>
                        {renderItem({ item, add, remove, fields })}
                    </div>
                }
                // const name = item.name;

                return <Panel column={column} index={index} extra={<Button disabled={minCount == fields.length} shape='round' size='small' icon={<DeleteOutlined />} danger onClick={() => remove(item.name)}>删除</Button>} key={item.key} items={items} title={title + (index + 1)} />
            })}
            <Button disabled={maxCount <= fields.length} type='dashed' block onClick={() => add({})}>{addText ? addText : '增加' + title}</Button>
        </FormControl.Group>
    }}</Form.List>
}
interface FormControlProps extends FormProps {
    children?: React.ReactNode
    labelWidth?: string | number
}
const FormControlContext = React.createContext(null)
const FormControl = ({ children, labelWidth, ...rest }: FormControlProps) => {
    return <FormControlContext.Provider value={{disabled:rest.disabled, labelWidth, labelAlign: rest.labelAlign, layout: rest.layout }}>
        <Form className="form-control-container" colon={false} {...rest} >
            {children}
        </Form>
    </FormControlContext.Provider>

}
FormControl.Group = ({ children }: any) => {
    return <Descriptions.Group>{children}</Descriptions.Group>
}
FormControl.Panel = Panel
FormControl.List = List
export default FormControl